#include "Tank.h"
#include "GameMap.h"
#include "define.h"

IMAGE* Tank::imgHero[4][4][2] = { NULL };				// 初始化我方坦克图片
IMAGE* Tank::imgEnemy[4][4][2] = { NULL };			// 初始化敌方坦克图片

// 有参构造函数
Tank::Tank(int owner, int row, int column, int direction)
{
	// 参数初始化
	this->owner = owner;
	this->row = row;
	this->column = column;
	this->oldRow = this->row;
	this->oldColumn = this->column;
	this->x = this->column * BLOCK_SIZE;
	this->y = this->row * BLOCK_SIZE;
	this->direction = direction;
	this->map = GameMap::getMap();

	// 加载敌我双方坦克图片（图片每一行装甲不同，这里没用装甲）
	if (imgHero[0][0][0] == NULL)
	{
		// 加载敌我坦克图片
		IMAGE imgTmp;
		loadimage(&imgTmp, "./resources/image/tank.png", BLOCK_SIZE * 16, BLOCK_SIZE * 16);			// 加载时扩大到合适尺寸，剪裁时就正好大小了
		SetWorkingImage(&imgTmp);			// 切换到绘图工作区
		for (int ar = 0; ar < 4; ar++)
		{
			for (int dir = 0; dir < 4; dir++)
			{
				for (int tr = 0; tr < 2; tr++)
				{
					// 我方坦克
					imgHero[ar][dir][tr] = new IMAGE;
					getimage(imgHero[ar][dir][tr], dir * BLOCK_SIZE * 4 + tr * BLOCK_SIZE * 2 - 1, ar * BLOCK_SIZE * 2, BLOCK_SIZE * 2, BLOCK_SIZE * 2);
					// 敌方坦克
					imgEnemy[ar][dir][tr] = new IMAGE;
					getimage(imgEnemy[ar][dir][tr], dir * BLOCK_SIZE * 4 + tr * BLOCK_SIZE * 2 - 1, BLOCK_SIZE * 8 + ar * BLOCK_SIZE * 2, BLOCK_SIZE * 2, BLOCK_SIZE * 2);
				}
			}
		}
		SetWorkingImage();					// 切换回窗口工作区
	}

	// 计时开始
	this->lastTime = GetTickCount64();
}

// 坦克绘制
void Tank::draw()
{
	// 绘制我方坦克
	if (this->owner == TANK_OWNER_HERO && this->status == TANK_STATUS_RUN)
	{
		myDrawImage(this->x, this->y, imgHero[this->armor][this->direction][this->track]);
	}
	// 绘制敌方坦克
	if (this->owner == TANK_OWNER_ENEMY && this->status == TANK_STATUS_RUN)
	{
		myDrawImage(this->x, this->y, imgEnemy[this->armor][this->direction][this->track]);
	}
}

// 坦克是否可以移动
bool Tank::moveValid(int direction)
{
	switch (direction)
	{
	case TANK_DIRECTION_UP:
		if (row == 0) { return false; }
		if (map[row - 1][column] > 0) { return false; }
		if (map[row - 1][column + 1] > 0) { return false; }
		break;
	case TANK_DIRECTION_DOWN:
		if (row == 24) { return false; }
		if (map[row + 2][column] > 0) { return false; }
		if (map[row + 2][column + 1] > 0) { return false; }
		break;
	case TANK_DIRECTION_LEFT:
		if (column == 0) { return false; }
		if (map[row][column - 1] > 0) { return false; }
		if (map[row + 1][column - 1] > 0) { return false; }
		break;
	case TANK_DIRECTION_RIGHT:
		if (column == 24) { return false; }
		if (map[row][column + 2] > 0) { return false; }
		if (map[row + 1][column + 2] > 0) { return false; }
		break;
	}
	return true;
}

// 坦克移动
bool Tank::move(int direction)
{
	// 如果坦克移动进程未完成则禁止再次移动
	if (this->oldRow != this->row) { return false; }
	if (this->oldColumn != this->column) { return false; }

	if (this->direction == direction)			// 方向相同则前进
	{
		//  判断是否可以移动
		if (!moveValid(direction)) { return false; }

		// 开始移动
		switch (direction)
		{
		case TANK_DIRECTION_UP:
			map[row + 1][column] = 0;
			map[row + 1][column + 1] = 0;
			map[row - 1][column] = owner;
			map[row - 1][column + 1] = owner;
			oldRow = row;
			row--;
			break;
		case TANK_DIRECTION_DOWN:
			map[row][column] = 0;
			map[row][column + 1] = 0;
			map[row + 2][column] = owner;
			map[row + 2][column + 1] = owner;
			oldRow = row;
			row++;
			break;
		case TANK_DIRECTION_LEFT:
			map[row][column + 1] = 0;
			map[row + 1][column + 1] = 0;
			map[row][column - 1] = owner;
			map[row + 1][column - 1] = owner;
			oldColumn = column;
			column--;
			break;
		case TANK_DIRECTION_RIGHT:
			map[row][column] = 0;
			map[row + 1][column] = 0;
			map[row][column + 2] = owner;
			map[row + 1][column + 2] = owner;
			oldColumn = column;
			column++;
			break;
		}
	}
	else    // 方向不同，仅调整方向不前进
	{
		this->direction = direction;
	}

	return true;
}

// 坦克射击
void Tank::shoot()
{
	// 射击冷却未到时间禁止发射
	unsigned long long currentTime = GetTickCount64();
	int addTime = (int)(currentTime - this->lastTime);
	if (addTime >= INTERVAL_BULLET_SHOOT)
	{
		this->lastTime = currentTime;
	}
	else
	{
		return;
	}

	// 在子弹池中寻找空闲的子弹
	Bullet* bullet = nullptr;
	int len = this->bulletPool.size();
	for (int i = 0; i < len; i++)
	{
		if (this->bulletPool[i].status == BULLET_STATUS_FREE)
		{
			bullet = &this->bulletPool[i];
			break;
		}
	}
	if (bullet == nullptr)			// 没有就增加一个
	{
		Bullet newBullet;
		newBullet.owner = this->owner;
		this->bulletPool.push_back(newBullet);	// 浅拷贝
		bullet = &bulletPool[len];
	}

	// 设置子弹位置
	bullet->direction = this->direction;
	switch (this->direction)
	{
	case TANK_DIRECTION_UP:
		bullet->x = this->column * BLOCK_SIZE + BLOCK_SIZE - BULLET_SIZE / 2;
		bullet->y = this->row * BLOCK_SIZE - BULLET_SIZE - 4;
		break;
	case TANK_DIRECTION_DOWN:
		bullet->x = this->column * BLOCK_SIZE + BLOCK_SIZE - BULLET_SIZE / 2;
		bullet->y = this->row * BLOCK_SIZE + 2 * BLOCK_SIZE + 4;
		break;
	case TANK_DIRECTION_LEFT:
		bullet->x = this->column * BLOCK_SIZE - BULLET_SIZE - 4;
		bullet->y = this->row * BLOCK_SIZE + BLOCK_SIZE - BULLET_SIZE / 2;
		break;
	case TANK_DIRECTION_RIGHT:
		bullet->x = this->column * BLOCK_SIZE + 2 * BLOCK_SIZE + 4;
		bullet->y = this->row * BLOCK_SIZE + BLOCK_SIZE - BULLET_SIZE / 2;
		break;
	}

	// 设置子弹状态
	bullet->status = BULLET_STATUS_RUN;

	// 我方坦克发出射击声音
	if (owner == TANK_OWNER_HERO) { myPlayAudio("./resources/audio/shoot.mp3"); }

}

// 坦克坐标映射到地图
void Tank::toMap()
{
	map[row][column] = owner;
	map[row][column + 1] = owner;
	map[row + 1][column] = owner;
	map[row + 1][column + 1] = owner;
}

// 坦克重置
void Tank::reset()
{
	map[row][column] = 0;
	map[row][column + 1] = 0;
	map[row + 1][column] = 0;
	map[row + 1][column + 1] = 0;
	if (owner == TANK_OWNER_HERO)
	{
		this->row = 24;
		this->column = 8;
		this->oldRow = this->row;
		this->oldColumn = this->column;
		this->x = this->column * BLOCK_SIZE;
		this->y = this->row * BLOCK_SIZE;
		this->direction = TANK_DIRECTION_UP;
		this->armor = 3;
	}
	else
	{
		this->row = 0;
		this->oldRow = 0;
		this->column = 0;
		this->oldColumn = 0;
		this->x = 0;
		this->y = 0;
	}
	this->status = TANK_STATUS_FREE;
}

// 得到子弹池
vector<Bullet>& Tank::getBulletPool()
{
	return this->bulletPool;
}
